
import pandas as pd
from scipy import optimize as opt
import numpy as np


def getalldata():  # 获取股票信息

    Stock = pd.read_csv("fianl_data.csv")
    return Stock


def lingotest():
    # 确定c,A,b,Aeq,beq
    c = np.array([40, 90])  # 目标函数变量系数
    A = np.array([[9, 7], [7, 20]])  # 不等式变量系数
    b = np.array([56, 70])  # 不等式变量值
    Aeq = np.array([[0, 0]])  # 等式变量系数
    beq = np.array([0])  # 等式变量值
    # 限制
    lim1 = (0, None)
    lim2 = (0, None)
    # 求解
    res = opt.linprog(-c, A, b, Aeq, beq, bounds=(lim1, lim2))
    # 输出结果
    return res


def lingo_solve1_fundment(y1, y2, p1, p2, x10, x20, x30, beta=0.95, wiga=0.1, c1=0.01, c2=0.02):
    '''
    from Mon to Thu fundemential

    @:arg unknow 未知量 x1 x2 x3  alpha ,z
    @:parameter  设定系数 beta = 0.95 wiga = 0.1
    @:parameter known
    已知量
    Y1,Y2 预测价格
    p1,p2 初始价格
    C1，C2 = 手续费率
    :return:  未知量 x1 x2 x3
    '''
    # 确定c,A,b,Aeq,beq
    # when x1>x10 x2>x20
    c = np.array([-y1 / p1 + c1, -y2 / p2 + c2, -1, 0, 0])  # 目标函数变量系数
    A = np.array([[0, 0, 0, 1, 1 / (1 - beta)], [-y1 / p1, -y2 / p2, -1, -1, -1]])  # 不等式变量系数<=
    b = np.array([wiga, -x10 - x20 - x30])  # 不等式变量值
    Aeq = np.array([[1 + c1, 1 + c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 + c1) * x10 + (1 + c2) * x20 + x30])  # 等式变量值
    # 限制
    lim1 = (x10, None)
    lim2 = (x20, None)
    lim3 = (0, None)
    lim4 = (None, None)
    lim5 = (None, None)
    # 求解# min
    res = opt.linprog(-c, A, b, Aeq, beq, bounds=(lim1, lim2, lim3, lim4, lim5))
    return res


def lingo_solve1(y1, y2, p1, p2, x10, x20, x30, beta=0.95, wiga=0.1, c1=0.01, c2=0.02):
    '''
    from Mon to Thu fundemential

    @:arg unknow 未知量 x1 x2 x3  alpha ,z
    @:parameter  设定系数 beta = 0.95 wiga = 0.1
    @:parameter known
    已知量
    Y1,Y2 预测价格
    p1,p2 初始价格
    C1，C2 = 手续费率
    :return:  未知量 x1 x2 x3
    
    '''
    # 确定c,A,b,Aeq,beq
    ##################### when x1>x10 x2>x20######################
    fun_min = 9999999
    final_solve = None
    c = np.array([-y1 / p1 + c1, -y2 / p2 + c2, -1, 0, 0])  # 目标函数变量系数
    A = np.array([[0, 0, 0, 1, 1 / (1 - beta)], [-y1 / p1, -y2 / p2, -1, -1, -1]])  # 不等式变量系数<=
    b = np.array([wiga, -x10 - x20 - x30])  # 不等式变量值
    Aeq = np.array([[1 + c1, 1 + c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 + c1) * x10 + (1 + c2) * x20 + x30])  # 等式变量值
    # 限制
    lim1 = (x10, None)
    lim2 = (x20, None)
    lim3 = (0, None)
    lim4 = (None, None)
    lim5 = (None, None)
    # 求解# min
    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim1, lim2, lim3, lim4, lim5))
    solve_success = res.get('success')
    print(res)
    if solve_success and res.get('fun') < fun_min:
        fun_min = min(res.get('fun'), fun_min)
        final_solve = res.get('x')
        # print(fun_min)
        # print(final_solve)
        # print(1)

    ################# when x1 > x10, x2 < x20#######################
    c = np.array([-y1 / p1 + c1, -y2 / p2 - c2, -1, 0, 0])
    Aeq = np.array([[1 + c1, 1 - c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 + c1) * x10 + (1 - c2) * x20 + x30])  # 等式变量值
    lim1 = (x10, None)
    lim2 = (0, x20)

    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim1, lim2, lim3, lim4, lim5))
    solve_success = res.get('success')

    if solve_success and res.get('fun') < fun_min:
        fun_min = res.get('fun')
        final_solve = res.get('x')
        # print(fun_min)
        # print(final_solve)
        # print(1)
    ################# when x1 < x10, x2 > x20#####################

    c = np.array([-y1 / p1 - c1, -y2 / p2 + c2, -1, 0, 0])
    Aeq = np.array([[1 - c1, 1 + c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 - c1) * x10 + (1 + c2) * x20 + x30])  # 等式变量值
    lim1 = (0, x10)
    lim2 = (x20, None)

    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim1, lim2, lim3, lim4, lim5))
    solve_success = res.get('success')
    if solve_success and res.get('fun') < fun_min:
        fun_min = res.get('fun')
        final_solve = res.get('x')
        # print(fun_min)
        # print(final_solve)
        # print(1)
    # 输出结果

    ################# when x1 < x10, x2 > x20#####################

    c = np.array([-y1 / p1 - c1, -y2 / p2 - c2, -1, 0, 0])
    Aeq = np.array([[1 - c1, 1 - c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 - c1) * x10 + (1 - c2) * x20 + x30])  # 等式变量值
    lim1 = (0, x10)
    lim2 = (x20, None)

    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim1, lim2, lim3, lim4, lim5))
    solve_success = res.get('success')
    if solve_success and res.get('fun') < fun_min:
        fun_min = res.get('fun')
        final_solve = res.get('x')
        # print(fun_min)
        # print(final_solve)
        # print(1)
    # 输出结果

    return final_solve[0:3]


def lingo_solve2(y2, p2, x20, x30, beta=0.95, wiga=0.1, c2=0.02):
    '''
        from Mon to Thu fundemential

        @:arg unknow 未知量 x2 x3  alpha ,z
        @:parameter  设定系数 beta = 0.95 wiga = 0.1
        @:parameter known
        已知量
        Y2 预测价格
        p2 初始价格
        C2 = 手续费率
        x20 x30 之前的财产
        :return:  移动后的 x2 x3
    '''
    # 确定c,A,b,Aeq,beq
    ######### when x2>x20#########
    fun_min = 9999999
    final_solve = None
    c = np.array([-y2 / p2 + c2, -1, 0, 0])  # 目标函数变量系数
    A = np.array([[0, 0, 1, 1 / (1 - beta)], [-y2 / p2, -1, -1, -1]])  # 不等式变量系数<=
    b = np.array([wiga, - x20 - x30])  # 不等式变量值
    Aeq = np.array([[1 + c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 + c2) * x20 + x30])  # 等式变量值
    # 限制
    lim2 = (x20, None)
    lim3 = (0, None)
    lim4 = (None, None)
    lim5 = (None, None)
    # 求解# min
    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim2, lim3, lim4, lim5))

    solve_success = res.get('success')
    if solve_success and res.get('fun') < fun_min:
        fun_min = res.get('fun')
        final_solve = res.get('x')
        #print(final_solve)

    ######### when x2<=x20
    c = np.array([-y2 / p2 - c2, -1, 0, 0])  # 目标函数变量系数
    Aeq = np.array([[1 - c2, 1, 0, 0]])  # 等式变量系数
    beq = np.array([(1 - c2) * x20 + x30])  # 等式变量值
    # 输出结果
    lim2 = (0, x20)
    res = opt.linprog(c, A, b, Aeq, beq, bounds=(lim2, lim3, lim4, lim5))
    if solve_success and res.get('fun') < fun_min:
        fun_min = res.get('fun')
        final_solve = res.get('x')
        #print(final_solve)

    return final_solve


if __name__ == '__main__':
    Stock = getalldata()

